package com.tledu.httpclient;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * 通过这个工具类发送请求
 * 通过封装简化的发送请求的操作
 *
 * @author cyrus
 */
public class HttpUtils {
    /**
     * 定义静态变量，发送请求的时候，可以都可以通过这个变量去发送了
     */
    private static final CloseableHttpClient httpClient;

    private static final String charset = "utf-8";

    /**
     * 初始这个变量
     */
    static {
        // 静态代码块，这一块在程序加载的时候就会执行
        // 我们可以在静态代码块里对变量进行初始化
        // 每次发送http请求的时候都会一些配置。我们可以在这里添加通用的配置
        // 设置请求超时时间
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(20000).build();
        // 根据这个配置创建了httpClient
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
    }

    /**
     * 封装get方法
     * 作用： 发送get请求
     * 输入什么：
     * url
     * 请求参数
     * 输出什么：
     * 输出一个请求之后结果
     */
    public static String get(String url, List<NameValuePair> params) throws IOException {
        if (url == null) {
            // 运行时异常，程序运行阶段提示的异常，
            throw new RuntimeException("请输入url");
        }

        if (params != null) {
            url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(params), charset);
        }
        // 2. 创建请求
        HttpGet httpGet = new HttpGet(url);
        // 3. 通过httpClient执行get请求,拿到请求结果
        CloseableHttpResponse response = httpClient.execute(httpGet);
        // 4. 对结果进行处理
        //  4.1 获取请求的状态码，请求状态200代表成功
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != 200) {
            // 请求失败了
            // 关闭这个请求
            httpGet.abort();
            throw new RuntimeException("请求失败，状态码为：" + statusCode);
        }
        // 请求成功
        // 5. 获取请求体
        HttpEntity entity = response.getEntity();
        String result="";
        // 拿到这个请求体之后，获取响应的结果
        if (entity != null) {
            // 通过这个api就可以拿到请求之后的字符串数据
            result = EntityUtils.toString(entity, "utf-8");
            // 释放支援
            EntityUtils.consume(entity);
            // 关闭这个响应
            response.close();
        }
        return result;
    }

    /**
     * 表单方式请求
     * @param url 请求的地址
     * @param params 请求的参数
     * @return 返回的结果
     */
    public static String postForm(String url, List<NameValuePair> params) throws IOException {
        if (url == null) {
            throw new RuntimeException("地址不能为null");
        }
        // 2. 创建post请求
        HttpPost httpPost = new HttpPost(url);
        if (params != null) {
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params,charset);
            // 5. 设置请求体
            httpPost.setEntity(formEntity);
        }
        // 6. 发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);
        // 7. 判断状态码
        int status = response.getStatusLine().getStatusCode();
        if (status != 200) {
            httpPost.abort();
            throw new RuntimeException("请求失败,当前的状态码为:" + status);
        }
        String result = "";
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            // 8. 获取请求结果
            result = EntityUtils.toString(entity);
            // 9. 关闭响应
            EntityUtils.consume(entity);
            response.close();
        }
        return result;
    }
}
